home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / mesademos / IMAGE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  4.9 KB  |  221 lines

  1. /* Lifted from libtk/image.c */
  2.  
  3. /* This code lets your read in SGI .rgb files. */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h> 
  7. #include <string.h>
  8. #include "image.h"
  9.  
  10. #ifndef SEEK_SET
  11. #  define SEEK_SET 0
  12. #endif
  13.  
  14.  
  15. /******************************************************************************/
  16.  
  17. typedef unsigned int GLuint;  /* Should be 32-bit value. */
  18. typedef int GLint;  /* Should be 32-bit value. */
  19.  
  20. typedef struct _rawImageRec {
  21.     unsigned short imagic;
  22.     unsigned short type;
  23.     unsigned short dim;
  24.     unsigned short sizeX, sizeY, sizeZ;
  25.     unsigned long min, max;
  26.     unsigned long wasteBytes;
  27.     char name[80];
  28.     unsigned long colorMap;
  29.     FILE *file;
  30.     unsigned char *tmp, *tmpR, *tmpG, *tmpB;
  31.     unsigned long rleEnd;
  32.     GLuint *rowStart;
  33.     GLint *rowSize;
  34. } rawImageRec;
  35.  
  36. /******************************************************************************/
  37.  
  38. static void ConvertShort(unsigned short *array, unsigned int length)
  39. {
  40.     unsigned short b1, b2;
  41.     unsigned char *ptr;
  42.  
  43.     ptr = (unsigned char *)array;
  44.     while (length--) {
  45.     b1 = *ptr++;
  46.     b2 = *ptr++;
  47.     *array++ = (b1 << 8) | (b2);
  48.     }
  49. }
  50.  
  51. static void ConvertUint(GLuint *array, unsigned int length)
  52. {
  53.     unsigned int b1, b2, b3, b4;
  54.     unsigned char *ptr;
  55.  
  56.     ptr = (unsigned char *)array;
  57.     while (length--) {
  58.     b1 = *ptr++;
  59.     b2 = *ptr++;
  60.     b3 = *ptr++;
  61.     b4 = *ptr++;
  62.     *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
  63.     }
  64. }
  65.  
  66. static rawImageRec *RawImageOpen(char *fileName)
  67. {
  68.     union {
  69.     int testWord;
  70.     char testByte[4];
  71.     } endianTest;
  72.     rawImageRec *raw;
  73.     int swapFlag;
  74.     int x;
  75.  
  76.     endianTest.testWord = 1;
  77.     if (endianTest.testByte[0] == 1) {
  78.     swapFlag = 1;
  79.     } else {
  80.     swapFlag = 0;
  81.     }
  82.  
  83.     raw = (rawImageRec *)malloc(sizeof(rawImageRec));
  84.     if (raw == NULL) {
  85.     fprintf(stderr, "Out of memory!\n");
  86.     exit(1);
  87.     }
  88.     if ((raw->file = fopen(fileName, "rb")) == NULL) {
  89.     perror(fileName);
  90.     exit(1);
  91.     }
  92.  
  93.     fread(raw, 1, 12, raw->file);
  94.  
  95.     if (swapFlag) {
  96.     ConvertShort(&raw->imagic, 6);
  97.     }
  98.  
  99.     raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
  100.     raw->tmpR = (unsigned char *)malloc(raw->sizeX*256);
  101.     raw->tmpG = (unsigned char *)malloc(raw->sizeX*256);
  102.     raw->tmpB = (unsigned char *)malloc(raw->sizeX*256);
  103.     if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
  104.     raw->tmpB == NULL) {
  105.     fprintf(stderr, "Out of memory!\n");
  106.     exit(1);
  107.     }
  108.  
  109.     if ((raw->type & 0xFF00) == 0x0100) {
  110.     x = raw->sizeY * raw->sizeZ * (int) sizeof(GLuint);
  111.     raw->rowStart = (GLuint *)malloc(x);
  112.     raw->rowSize = (GLint *)malloc(x);
  113.     if (raw->rowStart == NULL || raw->rowSize == NULL) {
  114.         fprintf(stderr, "Out of memory!\n");
  115.         exit(1);
  116.     }
  117.     raw->rleEnd = 512 + (2 * x);
  118.     fseek(raw->file, 512, SEEK_SET);
  119.     fread(raw->rowStart, 1, x, raw->file);
  120.     fread(raw->rowSize, 1, x, raw->file);
  121.     if (swapFlag) {
  122.         ConvertUint(raw->rowStart,
  123.             (unsigned int) (x/sizeof(GLuint)));
  124.         ConvertUint((GLuint *)raw->rowSize,
  125.             (unsigned int) (x/sizeof(GLint)));
  126.     }
  127.     }
  128.     return raw;
  129. }
  130.  
  131. static void RawImageClose(rawImageRec *raw)
  132. {
  133.  
  134.     fclose(raw->file);
  135.     free(raw->tmp);
  136.     free(raw->tmpR);
  137.     free(raw->tmpG);
  138.     free(raw->tmpB);
  139.     free(raw);
  140. }
  141.  
  142. static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
  143. {
  144.     unsigned char *iPtr, *oPtr, pixel;
  145.     int count;
  146.  
  147.     if ((raw->type & 0xFF00) == 0x0100) {
  148.     fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
  149.     fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
  150.           raw->file);
  151.  
  152.     iPtr = raw->tmp;
  153.     oPtr = buf;
  154.     for (;;) {
  155.         pixel = *iPtr++;
  156.         count = (int)(pixel & 0x7F);
  157.         if (!count) {
  158.         return;
  159.         }
  160.         if (pixel & 0x80) {
  161.         while (count--) {
  162.             *oPtr++ = *iPtr++;
  163.         }
  164.         } else {
  165.         pixel = *iPtr++;
  166.         while (count--) {
  167.             *oPtr++ = pixel;
  168.         }
  169.         }
  170.     }
  171.     } else {
  172.     fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
  173.           SEEK_SET);
  174.     fread(buf, 1, raw->sizeX, raw->file);
  175.     }
  176. }
  177.  
  178. static void RawImageGetData(rawImageRec *raw, RGBImageRec *final)
  179. {
  180.     unsigned char *ptr;
  181.     int i, j;
  182.  
  183.     final->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
  184.     if (final->data == NULL) {
  185.     fprintf(stderr, "Out of memory!\n");
  186.     exit(1);
  187.     }
  188.  
  189.     ptr = final->data;
  190.     for (i = 0; i < (int)(raw->sizeY); i++) {
  191.     RawImageGetRow(raw, raw->tmpR, i, 0);
  192.     RawImageGetRow(raw, raw->tmpG, i, 1);
  193.     RawImageGetRow(raw, raw->tmpB, i, 2);
  194.     for (j = 0; j < (int)(raw->sizeX); j++) {
  195.         *ptr++ = *(raw->tmpR + j);
  196.         *ptr++ = *(raw->tmpG + j);
  197.         *ptr++ = *(raw->tmpB + j);
  198.     }
  199.     }
  200. }
  201.  
  202. RGBImageRec *RGBImageLoad(char *fileName)
  203. {
  204.     rawImageRec *raw;
  205.     RGBImageRec *final;
  206.  
  207.     raw = RawImageOpen(fileName);
  208.     final = (RGBImageRec *)malloc(sizeof(RGBImageRec));
  209.     if (final == NULL) {
  210.     fprintf(stderr, "Out of memory!\n");
  211.     exit(1);
  212.     }
  213.     final->sizeX = raw->sizeX;
  214.     final->sizeY = raw->sizeY;
  215.     RawImageGetData(raw, final);
  216.     RawImageClose(raw);
  217.     return final;
  218. }
  219.  
  220. /******************************************************************************/
  221.